﻿using System;
using SimpleServiceBus.Messages.Management.Monitoring;

namespace SimpleServiceBus.Endpoint.Management.Monitoring
{ //not threadsafe
    public abstract class EndpointStatusProbeBase : IEndpointStatusProbe

    {
        private bool _canAggregate = true;
        public IMessagingEndpoint Endpoint { get; private set; }

        #region IEndpointStatusProbe Members

        public string Name { get; set; }
        public string UnitOfMeasurement { get; set; }
        public MeasurementDataType DataType { get; set; }

        public bool CanAggregate
        {
            get { return _canAggregate; }
            set { _canAggregate = value; }
        }

        public virtual EndpointMeasurement TakeMeasurement(IMessagingEndpoint endpoint)
        {
            Endpoint = endpoint;

            object value = null;

            TakeMeasurement(ref value);

            return CreateEndpointMeasurement(Name, value, UnitOfMeasurement, CanAggregate, DataType);
        }

        object ICloneable.Clone()
        {
            return MemberwiseClone();
        }

        #endregion

        public EndpointStatusProbeBase Clone()
        {
            return (EndpointStatusProbeBase) ((ICloneable) this).Clone();
        }

        protected virtual EndpointMeasurement CreateEndpointMeasurement(string name, object value,
                                                                        string unitOfMeasurement, bool canAggregate,
                                                                        MeasurementDataType dataType)
        {
            return new EndpointMeasurement
                       {
                           Timestamp = DateTime.Now.ToUniversalTime(),
                           Name = name,
                           Value = value != null ? value.ToString() : String.Empty,
                           UnitOfMeasurement = unitOfMeasurement,
                           CanAggregate = canAggregate,
                           DataType = dataType
                       };
        }

        protected abstract void TakeMeasurement(ref object value);
    }
}